﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

namespace EventScavenger
{
    public partial class BulkAddMachineLogs : Form
    {
        private EventScavengerDAL eventScavengerDAL;

        public BulkAddMachineLogs()
        {
            InitializeComponent();
        }
        public DialogResult ShowDialog(EventScavengerDAL sqlEventSource)
        {
            eventScavengerDAL = sqlEventSource;
            return ShowDialog();
        }

        #region Form events
        private void BulkAddMachineLogs_Load(object sender, EventArgs e)
        {
            cboLogs.SelectedIndex = 0;
            LoadCollectors();
            LoadPollFilters();
            EnableBulkAddButton();
        }
        #endregion

        #region Button events
        private void cmdAddFromFile_Click(object sender, EventArgs e)
        {
            if (openFileDialogAddMachines.ShowDialog() == DialogResult.OK)
            {
                Cursor.Current = Cursors.WaitCursor;
                string[] machineNames = System.IO.File.ReadAllLines(openFileDialogAddMachines.FileName);
                foreach (string machineName in machineNames)
                {
                    if (!lstMachines.Items.Contains(machineName.Trim()))
                    {
                        try
                        {
                            if (chkValidate.Checked && System.Net.Dns.GetHostAddresses(machineName.Trim()).Length == 0)
                            {
                                if (MessageBox.Show(string.Format("The machine {0} is not available or cannot be contacted\r\nWould you like to add it to the list anyway?",
                                    machineName), "Add machine", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No)
                                    return;
                            }
                        }
                        catch (Exception ex)
                        {
                            if (MessageBox.Show(string.Format("The machine {0} is not available or cannot be contacted\r\nWould you like to add it to the list anyway?\r\nError details: {1}",
                                    machineName, ex.Message), "Add machine", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No)
                                return;
                        }
                        lstMachines.Items.Add(machineName.Trim());
                        
                    }
                }
                Cursor.Current = Cursors.Default;
                EnableBulkAddButton();
            }
        }
        private void cmdAddMachine_Click(object sender, EventArgs e)
        {
            AddMachine();
        }
        private void cmdAdd_Click(object sender, EventArgs e)
        {
            bool success = true;
            List<MachineLogEntry> existingLogs = eventScavengerDAL.GetMachineLogList(false);

            foreach (object item in lstMachines.Items)
            {
                string machineName = item.ToString();
                try
                {
                    Cursor.Current = Cursors.WaitCursor;
                    foreach (string logName in GetEventLogs(machineName))
                    {
                        if ((from ml in existingLogs
                             where ml.Machine == machineName && ml.LogName == logName
                             select ml).Count() == 0)
                        {
                            try
                            {
                                MachineLogEntry entry = new MachineLogEntry(machineName, logName);
                                entry.LastPollTime = new DateTime(2000, 1, 1);
                                entry.CollectorId = ((Collector)cboCollector.SelectedItem).Id;
                                entry.Enabled = chkEnabled.Checked;
                                entry.PollFrequency = (int)frequencyNumericUpDown.Value;
                                entry.MaxEntryCount = (int)numericUpDownMaxEntries.Value;
                                entry.PollFilterID = 0;
                                if (cboPollingFilter.SelectedItem != null)
                                {
                                    entry.PollFilterID = ((PollFilter)cboPollingFilter.SelectedItem).PollFilterID;
                                }
                                eventScavengerDAL.UpdateMachineLogEntry(entry);
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show(string.Format("There was a problem adding the entry {0}\\{1}\r\n{2}",
                                    machineName, logName, ex.Message), "Adding", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                success = false;
                            }
                        }
                        else if (! chkIgnoreDuplicates.Checked)
                        {
                            MessageBox.Show(string.Format("The entry {0}\\{1} already exists in the database!",
                                   machineName, logName), "Adding", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                        }
                    }
                }
                catch (Exception ex)
                {
                    success = false;
                    MessageBox.Show(string.Format("There was a problem accessing the machine {0}\r\nError details: {1}",
                                    machineName, ex.Message), "Adding", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                Cursor.Current = Cursors.Default;
            }
            if (success)
            {
                if (MessageBox.Show("Specified event logs have been added to the database.\r\nDo you want to bulk add more machines?\r\nPlease remember to restart the collector services for changes to apply.", "Done", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
                {
                    DialogResult = DialogResult.OK;
                    Close();
                }
            }
        }
        #endregion

        #region private methods
        private void LoadCollectors()
        {
            try
            {
                List<Collector> collectors = eventScavengerDAL.GetCollectorList();
                foreach (Collector collector in collectors)
                {
                    cboCollector.Items.Add(collector);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private void LoadPollFilters()
        {
            try
            {
                List<PollFilter> pollfilters = eventScavengerDAL.GetPollingFilterList();
                cboPollingFilter.Items.Add(new PollFilter() { PollFilterID = -1, Name = "(None)" });
                foreach (PollFilter pollfilter in pollfilters)
                {
                    cboPollingFilter.Items.Add(pollfilter);
                }
                cboPollingFilter.SelectedIndex = 0;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private void AddMachine()
        {
            if (txtMachine.Text.Trim().Length > 0)
            {
                if (!lstMachines.Items.Contains(txtMachine.Text.Trim()))
                {
                    try
                    {
                        if (chkValidate.Checked && System.Net.Dns.GetHostAddresses(txtMachine.Text.Trim()).Length == 0)
                        {
                            if (MessageBox.Show(string.Format("The machine {0} is not available or cannot be contacted\r\nWould you like to add it to the list anyway?",
                                txtMachine.Text), "Add machine", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No)
                                return;
                        }
                    }
                    catch (Exception ex)
                    {
                        if (MessageBox.Show(string.Format("The machine {0} is not available or cannot be contacted\r\nWould you like to add it to the list anyway?\r\nError details: {1}",
                                txtMachine.Text, ex.Message), "Add machine", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No)
                            return;
                    }
                    lstMachines.Items.Add(txtMachine.Text.Trim());
                    txtMachine.Text = "";
                    EnableBulkAddButton();
                }
            }
        }
        private void DeleteSelectedItem()
        {
            if (lstMachines.SelectedItems.Count > 0)
            {
                if (MessageBox.Show("Are you sure you want to remove these machine(s) from the list?", "Remove", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    for(int i = lstMachines.SelectedItems.Count; i > 0 ; i--)
                    {
                        lstMachines.Items.Remove(lstMachines.SelectedItems[0]);
                    }
                    EnableBulkAddButton();
                }
            }
        }
        private void EnableBulkAddButton()
        {
            cmdAdd.Enabled = lstMachines.Items.Count > 0 && cboCollector.SelectedIndex > -1;
            lblBulkAddEnableReason.Text = "";
            if (lstMachines.Items.Count == 0)
                lblBulkAddEnableReason.Text = "No machines in list";
            else if (cboCollector.SelectedIndex == -1)
                lblBulkAddEnableReason.Text = "Please specify collector";
        }
        private string[] GetEventLogs(string machineName)
        {
            string[] logs = new string[] { "Application" };
            switch (cboLogs.SelectedIndex)
            {
                case 0:
                    logs = new string[] { "Application" };
                    break;
                case 1:
                    logs = new string[] { "System" };
                    break;
                case 2:
                    logs = new string[] { "Security" };
                    break;
                case 3:
                    logs = new string[] { "Application", "System" };
                    break;
                case 4:
                    logs = new string[] { "Application", "System", "Security" };
                    break;
                case 5:
                    if (machineName.Length > 0 && System.Net.Dns.GetHostAddresses(machineName).Length > 0)
                    {
                        EventLog[] eventLogs = EventLog.GetEventLogs(machineName);
                        logs = new string[eventLogs.Length];
                        for (int i = 0; i < logs.Length; i++)
                        {
                            logs[i] = eventLogs[i].Log;
                        }
                    }
                    break;
                default:
                    logs = new string[1] { "Application" };
                    break;
            }
            return logs;
        }
        #endregion

        #region control events
        private void lstMachines_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete)
            {
                DeleteSelectedItem();
            }
        }
        private void txtMachine_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                AddMachine();
            }
        }
        private void cboLogs_SelectedIndexChanged(object sender, EventArgs e)
        {
            string explain = "";
            switch (cboLogs.SelectedIndex)
            {
                case 0:
                    explain = "Only the Application event log";
                    break;
                case 1:
                    explain = "Only the System event log";
                    break;
                case 2:
                    explain = "Only the Security event log";
                    break;
                case 3:
                    explain = "Application and System event logs";
                    break;
                case 4:
                    explain = "Application, System and Security logs";
                    break;
                case 5:
                    explain = "All event logs";
                    break;
                default:
                    explain = "";
                    break;
            }
            lblLogExplain.Text = explain;
        }
        private void cboCollector_SelectedIndexChanged(object sender, EventArgs e)
        {
            EnableBulkAddButton();
        }
        #endregion
    }
}
